package db;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import model.Accion;
import model.Hecho;
import model.Precio;
import model.Regla;

public class HibernateDAO implements DAO {
	
	private SessionFactory sessionFactory = null;
	
	private SessionFactory getSessionFactory(){
		if (sessionFactory == null){
			sessionFactory = new Configuration().configure().buildSessionFactory();
		}
		return sessionFactory;
	}
	
	private Session getCurrentSession(){
		return getSessionFactory().getCurrentSession();
	}

	@Override
	public Long saveAccion(Accion a) throws Exception {
		Session s = null;
		Transaction t = null;
		try {
			s = getCurrentSession();
			t = s.beginTransaction();
			s.saveOrUpdate(a);		
			t.commit();
			return a.getId();
		} catch (Exception e){
			if (t != null){
				t.rollback();
			}
			throw e;
		}
	}

	@Override
	public Accion getAccion(Long id) {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		Accion a = (Accion) s.get(Accion.class, id);
		t.commit();
		return a;
	}

	@Override
	public Long savePrecio(Precio p) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Precio getPrecio(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void saveUpdateAcciones(List<Accion> l) throws Exception {
		for (Accion a : l){
			saveAccion(a);		
		}
	}

	@Override
	public Accion getAccionByRic(String ric) {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		Accion a = (Accion) s.createQuery("from Accion a where a.ric = :ric").setString("ric", ric).uniqueResult();
		t.commit();
		return a;
	}
	
	public List<Accion> getAcciones() {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		List<Accion> lista = s.createQuery("select a from Accion a ").list();
		t.commit();
		return lista;
	}
	
	@Override
	public List<Regla> getReglas() {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		SQLQuery sql = s.createSQLQuery("select reg_id, reg_ant, reg_ant1, reg_cons, reg_union from reglas");
		List l = sql.list();
		List<Regla> reglas = new ArrayList<Regla>();
		for (Object o : l){
			Object[] data = (Object[]) o;
			Regla r = new Regla();
			BigDecimal idBig = (BigDecimal) data[0];
			r.id = idBig.intValue();		
			r.ant = (String) data[1];
			r.ant1 = (String) data[2];
			r.cons = (String) data[3];
			r.union = (String) data[4];
			
			reglas.add(r);
		}
		t.commit();		
		return reglas;
	}
	
	@Override
	public List<Hecho> getHechos() {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		SQLQuery sql = s.createSQLQuery("select hho_id, hho_descripcion from hecho");
		List l = sql.list();
		List<Hecho> hechos = new ArrayList<Hecho>();
		for (Object o : l){
			Object[] data = (Object[]) o;
			Hecho h = new Hecho();
			BigDecimal idBig = (BigDecimal) data[0];
			h.id = idBig.intValue();		
			h.descripcion = (String) data[1];
			
			hechos.add(h);
		}
		t.commit();		
		return hechos;
	}
	
	@Override
	public void borrarRegla(Integer id) {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		SQLQuery sql = s.createSQLQuery("delete from reglas where reg_id = " + id);
		sql.executeUpdate();
		t.commit();
	}
	
	@Override
	public void borrarHechos() {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		SQLQuery sql = s.createSQLQuery("delete from hecho");
		sql.executeUpdate();
		t.commit();
	}
	
	@Override
	public void saveHecho(String descripcion) {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		SQLQuery sql = s.createSQLQuery("insert into hecho (hho_id, hho_descripcion) values (nextval('hecho_hho_id_seq'), '" + descripcion + "')" );
		sql.executeUpdate();
		t.commit();		
	}
	
	@Override
	public void saveRegla(Regla r) {
		Session s = getCurrentSession();
		Transaction t = s.beginTransaction();
		SQLQuery sql = s.createSQLQuery("insert into reglas (reg_id, reg_ant, reg_cons) values (nextval('reglas_reg_id_seq'), '" + r.ant + "' , '" + r.cons + "')" );
		sql.executeUpdate();
		t.commit();		
	}
	
	
}
